package com.channel.temperature.collect.ui.viewmodel

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.hjq.toast.ToastUtils
import com.hjy.bluetooth.exception.BluetoothException
import com.hjy.bluetooth.inter.SendCallBack
import com.hjy.bluetooth.operator.abstra.Sender
import com.channel.temperature.collect.app.ext.mmkv
import com.channel.temperature.collect.app.util.CRC16Utils
import com.channel.temperature.collect.app.util.MyUtil
import com.channel.temperature.collect.data.annotation.ValueKey
import com.channel.temperature.collect.data.response.SystemInfoBean
import kotlinx.coroutines.launch
import me.hgj.mvvmhelper.base.BaseViewModel

class SystemSettingModel : BaseViewModel() {

    var tipslistData = MutableLiveData<ArrayList<String>>()
    var clickType = 0
    var checkTimeCMDSendTime = ""
    var closeWaitDialog = MutableLiveData<Boolean>()
    lateinit var readedSystemInfo: SystemInfoBean
    lateinit var sendedSystemInfo: SystemInfoBean
    var updateUI = MutableLiveData<Boolean>()  //  通知更新UI
    var systemAddress = 0
    var continueSendWakeUpCMD = true
    var otherPackageData = ByteArray(80)
    fun addMessage(msg: String) {
        viewModelScope.launch {
            var tempList = tipslistData.value
            if (tempList == null) {
                tempList = ArrayList<String>()
            }
            tempList.add(msg)
            tipslistData.value = tempList!!
        }
    }

    fun sendCommonCMD(mSender: Sender, value: String) {
        viewModelScope.launch {
            var bufData = MyUtil.hex2Bytes(value)
            Log.e("sendCommonCMD", "sendCommonCMD  " + value)
            mSender?.send(bufData, object : SendCallBack {
                override fun onSending(command: ByteArray) {
                    addMessage("命令发送中... " + MyUtil.bytes2Hex(command))
                }

                override fun onSendFailure(bleException: BluetoothException) {
                    Log.e("onSendFailure", "onSendFailure " + bleException.message.toString())
                }
            })
        }
    }

    fun sendResetCMD(mSender: Sender, value: String) {
        viewModelScope.launch {
            var bufData = MyUtil.hex2Bytes(value)
            mSender?.send(bufData, object : SendCallBack {
                override fun onSending(command: ByteArray) {
                    addMessage("命令发送中... " + MyUtil.bytetoString(command))
                }

                override fun onSendFailure(bleException: BluetoothException) {
                    Log.e("onSendFailure", "onSendFailure " + bleException.message.toString())
                }
            })
        }
    }

    fun clearTips() {
        tipslistData.value = ArrayList<String>()
    }

    var packageDataLength: Int = 0
    var resultDataLength: Int = 0
    var needFoldData = false
    var dataResult: ByteArray = ByteArray(215)
    fun handleBLEResult(data: ByteArray) {
        if (data.size > 2) {
            when (clickType) {
                //1:复位 2：关机 3：唤醒设备 4：进入休眠 5：校时 6：清空flash 7：读取存储数量 8:设备信息 9:读系统参数 10：写系统参数 13；修改波特率 14：读取存储压力计算系数
                1 -> {
                    if (data[data.size - 2].toInt() == 0x5A) {
                        addMessage("复位成功")
                    } else if (data[data.size - 2].toInt() == 0xFF) {
                        addMessage("复位操作失败")
                    }
                }

                2 -> {
                    if (data[data.size - 2].toInt() == 0x5A) {
                        addMessage("关机成功")
                    } else if (data[data.size - 2].toInt() == 0xFF) {
                        addMessage("关机操作失败")
                    }
                }

                3 -> {

                    if (data[data.size - 2].toInt() == 0x5A) {
                        addMessage("唤醒设备成功")
                        continueSendWakeUpCMD = false
                    } else if (data[data.size - 2].toInt() == 0xFF) {
                        addMessage("唤醒设备操作失败")
                    }
                }

                4 -> {
                    if (data[data.size - 2].toInt() == 0x5A) {
                        addMessage("进入休眠成功")
                    } else if (data[data.size - 2].toInt() == 0xFF) {
                        addMessage("进入休眠操作失败")
                    }
                }

                5 -> {
                    var dataHex = MyUtil.bytes2Hex(data)
                    addMessage("校时返回数据 ：" + MyUtil.bytes2Hex(data))
                    if (dataHex.substring(
                            dataHex.length - 14, dataHex.length - 2
                        ) == checkTimeCMDSendTime
                    ) {
//                    addMessage("校时成功")
                    } else {
//                    addMessage("校时失败")
                    }
                }

                11 -> {
                    addMessage("读取数据成功 ：" + MyUtil.bytes2Hex(data))
                }

                6 -> {
                    if (data[data.size - 2].toInt() == 0x5A) {
                        addMessage("清空Flash成功")
                        closeWaitDialog.value = true

                    } else if (data[data.size - 2].toInt() == 0xFF) {
                        addMessage("清空Flash失败")
                        closeWaitDialog.value = true
                    }
                }

                7 -> {
                    var dataHex = MyUtil.bytes2Hex(data)
                    var flash2Size =
                        "" + (dataHex.substring(dataHex.length - 10, dataHex.length - 2).toInt(16)
                            .toDouble() / 1024.0) + " KB"
//                var flash2UsedSize =
//                    "" + (dataHex.substring(dataHex.length - 18, dataHex.length - 10).toInt(16)
//                        .toDouble() / 1024.0) + " KB"
                    var flash1Size =
                        "" + (dataHex.substring(dataHex.length - 26, dataHex.length - 18).toInt(16)
                            .toDouble() / 1024.0) + " KB"
//                var flash1UsedSize =
//                    "" + (dataHex.substring(dataHex.length - 34, dataHex.length - 26).toInt(16)
//                        .toDouble() / 1024.0) + " KB"
                    var totalSize =
                        "" + (dataHex.substring(dataHex.length - 42, dataHex.length - 34).toInt(16)
                            .toDouble() / 1024.0) + "KB"
                    addMessage("存储总量:$totalSize ,Flash1已存储量：$flash1Size ,Flash2储量地址：$flash2Size")
                }

                8 -> {
                    var dataHex = MyUtil.bytes2Hex(data)
                    var hardwareVersion =
                        dataHex.substring(dataHex.length - 6, dataHex.length - 2).toInt(16)
                    var softwareVersion =
                        dataHex.substring(dataHex.length - 10, dataHex.length - 6).toInt(16)
                    var deviceID = dataHex.substring(dataHex.length - 24, dataHex.length - 10)
                    addMessage("设备ID号：$deviceID , 软件版本:$softwareVersion ,硬件版本$hardwareVersion")
                }

                9 -> {
                    var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                    viewModelScope.launch {
                        if ("FF55AA" == hexResult) {
                            packageDataLength = 0
                            resultDataLength = MyUtil.bytes2Hex(data.copyOfRange(3, 5)).toInt(16)
                            dataResult = ByteArray(resultDataLength + 5)
                            needFoldData = data.size < resultDataLength + 5
                        }
                        if (needFoldData) {
                            System.arraycopy(data, 0, dataResult, packageDataLength, data.size)
                            packageDataLength += data.size
                            needFoldData = packageDataLength != resultDataLength + 5
                            if (packageDataLength == resultDataLength + 5) {
                                var packageData = dataResult.copyOfRange(0, dataResult.size - 1)
                                var result = CRC16Utils.checkCRC(packageData)

                                if (result.toInt(16) == java.lang.Byte.toUnsignedInt(dataResult[dataResult.size - 1])) {
                                    handleTask(dataResult)
                                } else {
                                    ToastUtils.show("命令校验失败")
                                }

                            }
                        } else {
                            var packageData = data.copyOfRange(0, data.size - 1)
                            var result = CRC16Utils.checkCRC(packageData)
                            if (result.toInt(16) == java.lang.Byte.toUnsignedInt(data[data.size - 1])) {
                                handleTask(data)
                            } else {
                                ToastUtils.show("命令校验失败")
                            }
                        }

                    }
                }

                10 -> {
                    var hexResult = MyUtil.bytes2Hex(data.copyOfRange(0, 3))
                    var dataHex = MyUtil.bytes2Hex(data)
                    if ("FF55AA" == hexResult && dataHex.substring(14, 16).toInt(16) == 2) {
                        addMessage("系统参数配置成功")
                        var json = Gson().toJson(sendedSystemInfo)
                        mmkv.putString(ValueKey.SYSTEM_INFO, json)
                        mmkv.putInt(ValueKey.DEVICE_ADDRESS, systemAddress)
                    }
                }

                13 -> {

                }

                14 -> {
                    Log.e("参数14", "参数14 ： " + MyUtil.bytes2Hex(data))
                    var result = CRC16Utils.checkCRC(data.copyOfRange(0, data.size - 1))
                    if (MyUtil.bytes2Hex(data)
                            .contains("FF55AA") && result.toInt(16) == java.lang.Byte.toUnsignedInt(
                            data[data.size - 1]
                        )
                    ) {
                        Log.e("参数14", "校验通过 ： ")

                        //                        var temperatureRatio1 = MyUtil.bytes2Double(data.copyOfRange(14, 22))
//                        var adcRatio1 = MyUtil.bytes2Double(data.copyOfRange(22, 30))
//                        var constant1 = MyUtil.bytes2Double(data.copyOfRange(30, 38))
//                        var temperatureRatio2 = MyUtil.bytes2Double(data.copyOfRange(38, 46))
//                        var adcRatio2 = MyUtil.bytes2Double(data.copyOfRange(46, 54))
//                        var constant2 = MyUtil.bytes2Double(data.copyOfRange(54, 62))

                        var rationResult = MyUtil.bytes2Hex(data.copyOfRange(14, 62))
                        Log.e("参数14", "参数14  ： " + rationResult)
                        if (rationResult.contains("FFFFFF")) {
                            ToastUtils.show("本设备未校准，请联系技术人员")
                        } else {
                            mmkv.putString(ValueKey.RATIO_KEY, rationResult)
                            ToastUtils.show("压力计算参数存储成功")
                        }

                    }
                }
            }
        }

    }

    fun handleTask(data: ByteArray) {
        viewModelScope.launch {
            Log.e("clickType", "clickType  9999 " + MyUtil.bytes2Hex(data))
            //9600波特率会分包，拆成64和一个50多的坑人
            //460800波特率 每包数据最大就有490长度，就不会分包了
            Log.e("执行了这里", "执行了这里")
            var dataHex = MyUtil.bytes2Hex(data)
            var address = dataHex.substring(28, 30).toInt(16)
            var outTime = dataHex.substring(30, 32).toInt(16)
            outTime = 30
            var intervalTime = dataHex.substring(32, 34).toInt(16)
            var workMode = dataHex.substring(34, 36).toInt(16)//0:空闲模式 1：离线模式 3：在线模式
            var onlineWorkTime = dataHex.substring(36, 40).toInt(16)
            var onlineWorkInterval = dataHex.substring(40, 44).toInt(16)

            otherPackageData = data.copyOfRange(22, 102)
            Log.e("clickType", "存的其它数据 " + MyUtil.bytes2Hex(otherPackageData))
            var mSystemData = SystemInfoBean(
                address,
                outTime,
                intervalTime,
                workMode,
                onlineWorkTime,
                onlineWorkInterval
            )
            var json = Gson().toJson(mSystemData)
            mmkv.putString(ValueKey.SYSTEM_INFO, json)
            mmkv.putInt(ValueKey.DEVICE_ADDRESS, address)
            readedSystemInfo = mSystemData
            updateUI.value = true
        }
    }
}